package com.ayh.campusfun.common.core;

import com.ayh.campusfun.common.exception.http.HttpException;
import com.ayh.campusfun.common.core.config.ExceptionCodeConfiguration;
import io.jsonwebtoken.ExpiredJwtException;
import io.jsonwebtoken.MalformedJwtException;
import io.jsonwebtoken.SignatureException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.BindException;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;

import javax.servlet.http.HttpServletRequest;
import java.sql.SQLIntegrityConstraintViolationException;

/**
 * @author ayh
 * @create 2021/3/23 0023 14:20
 * 全局异常处理
 */

// 标明一个异常处理类
@ControllerAdvice
public class GlobalExceptionAdvice {

    @Autowired
    private ExceptionCodeConfiguration codeConfiguration;

//    异常处理器
    @ExceptionHandler(value = Exception.class)
    @ResponseStatus(code = HttpStatus.INTERNAL_SERVER_ERROR)
    @ResponseBody
    public UnifyResponse handleException(HttpServletRequest request, Exception e){
        e.printStackTrace();
        String requestUrl = request.getRequestURI();
        String method = request.getMethod();
        return  new UnifyResponse(9999,"服务器异常!",method + " " + requestUrl);
    }

    @ExceptionHandler(value = HttpRequestMethodNotSupportedException.class)
    @ResponseStatus(code = HttpStatus.METHOD_NOT_ALLOWED)
    @ResponseBody
    public UnifyResponse handleMethodNotSupportedException(HttpServletRequest request, Exception e){
        e.printStackTrace();
        String requestUrl = request.getRequestURI();
        String method = request.getMethod();
        return  new UnifyResponse(40005,codeConfiguration.getMessage(40005),method + " " + requestUrl);
    }

    @ExceptionHandler(value = IllegalArgumentException.class)
    @ResponseStatus(code = HttpStatus.INTERNAL_SERVER_ERROR)
    @ResponseBody
    public UnifyResponse handleIllegalArgumentException(HttpServletRequest request, Exception e){
        e.printStackTrace();
        String requestUrl = request.getRequestURI();
        String method = request.getMethod();
        return  new UnifyResponse(60001,codeConfiguration.getMessage(60001),method + " " + requestUrl);
    }

    @ExceptionHandler(value = MalformedJwtException.class)
    @ResponseStatus(code = HttpStatus.INTERNAL_SERVER_ERROR)
    @ResponseBody
    public UnifyResponse handleMalformedJwtException(HttpServletRequest request, Exception e){
        e.printStackTrace();
        String requestUrl = request.getRequestURI();
        String method = request.getMethod();
        return  new UnifyResponse(60002,codeConfiguration.getMessage(60002),method + " " + requestUrl);
    }

    @ExceptionHandler(value = SQLIntegrityConstraintViolationException.class)
    @ResponseStatus(code = HttpStatus.INTERNAL_SERVER_ERROR)
    @ResponseBody
    public UnifyResponse handleSQLIntegrityConstraintViolationException(HttpServletRequest request, Exception e){
        e.printStackTrace();
        String requestUrl = request.getRequestURI();
        String method = request.getMethod();
        return  new UnifyResponse(70001,codeConfiguration.getMessage(70001),method + " " + requestUrl);
    }

    @ExceptionHandler(value = SignatureException.class)
    @ResponseStatus(code = HttpStatus.INTERNAL_SERVER_ERROR)
    @ResponseBody
    public UnifyResponse handleSignatureException(HttpServletRequest request, Exception e){
        e.printStackTrace();
        String requestUrl = request.getRequestURI();
        String method = request.getMethod();
        return  new UnifyResponse(60003,codeConfiguration.getMessage(60003),method + " " + requestUrl);
    }

    @ExceptionHandler(value = ExpiredJwtException.class)
    @ResponseStatus(code = HttpStatus.INTERNAL_SERVER_ERROR)
    @ResponseBody
    public UnifyResponse handleExpiredJwtException(HttpServletRequest request, Exception e){
        e.printStackTrace();
        String requestUrl = request.getRequestURI();
        String method = request.getMethod();
        return  new UnifyResponse(60000,codeConfiguration.getMessage(60000),method + " " + requestUrl);
    }

    @ExceptionHandler(value = MissingServletRequestParameterException.class)
    @ResponseStatus(code = HttpStatus.INTERNAL_SERVER_ERROR)
    @ResponseBody
    public UnifyResponse handleMissingServletRequestParameterException(HttpServletRequest request, Exception e){
        e.printStackTrace();
        String requestUrl = request.getRequestURI();
        String method = request.getMethod();
        return  new UnifyResponse(10001,codeConfiguration.getMessage(10001),method + " " + requestUrl);
    }

    @ExceptionHandler(value = BindException.class)
    @ResponseStatus(code = HttpStatus.INTERNAL_SERVER_ERROR)
    @ResponseBody
    public UnifyResponse handleBindExceptionException(HttpServletRequest request, Exception e){
        e.printStackTrace();
        String requestUrl = request.getRequestURI();
        String method = request.getMethod();
        return  new UnifyResponse(10002,codeConfiguration.getMessage(10002),method + " " + requestUrl);
    }

    @ExceptionHandler(value = HttpException.class)
    public ResponseEntity<UnifyResponse> handleHttpException(HttpServletRequest request, HttpException e){
        e.printStackTrace();
        String requestUrl = request.getRequestURI();
        String method = request.getMethod();
        HttpHeaders httpHeaders = new HttpHeaders();
        HttpStatus httpStatus = HttpStatus.resolve(e.getHttpStatusCode());
        httpHeaders.setContentType(MediaType.APPLICATION_JSON);
        UnifyResponse unifyResponse = new UnifyResponse(
                e.getCode()
                ,codeConfiguration.getMessage(e.getCode())
                ,method + " " + requestUrl);
        assert httpStatus != null;
        return new ResponseEntity<UnifyResponse>(unifyResponse,httpHeaders,httpStatus);
    }
}
